using System;
using System.Collections.Generic;
using System.Text;
using SpoonCore2.Client;
using SpoonCore2.Message;
using SpoonCore2.Tools;

namespace SpoonCore2.Service.Lock
{
	public class LockService : AbstractService
	{
		private static readonly SpoonIdentifier _id = SpoonIdentifier.Parse("1D2CEE8FD361F0B079E8C75556937ED4");

		private readonly SortedList<SpoonIdentifier, SortedList<SpoonIdentifier, LockItem>> _data = new SortedList<SpoonIdentifier, SortedList<SpoonIdentifier, LockItem>>();
		private readonly SortedList<SpoonIdentifier, DataWaiter<LockMessage>> _waiter = new SortedList<SpoonIdentifier, DataWaiter<LockMessage>>();

		public override SpoonIdentifier Id { get { return _id; } }

		public override void Dispose()
		{

		}

		public override void Init()
		{
			Handler.Register(new MessageHandler.ReceiveMessageHandler<LockMessage>(MessageReceive));
		}

		private void MessageReceive(ClientInfo sender, LockMessage message)
		{
			if (message.Message == LockMessage.MessageType.Request)
			{
				if (!_data.ContainsKey(message.ServiceId)) _data.Add(message.ServiceId, new SortedList<SpoonIdentifier, LockItem>());
				if (message.Lock == LockMessage.LockType.Request) _data[message.ServiceId].Add(message.Id, new LockItem()); //TODO just fake
				if (message.Lock == LockMessage.LockType.Release) _data[message.ServiceId].Remove(message.Id);

				message.Message = LockMessage.MessageType.Response;
				sender.Send(message);
			}
			else if (message.Message == LockMessage.MessageType.Response)
			{
				if (_waiter.ContainsKey(message.RequestId)) _waiter[message.RequestId].Data = message;
			}
		}

		public void Request(IService service, SpoonIdentifier id)
		{
			LockMessage msg = new LockMessage(service.Id, id);
			DataWaiter<LockMessage> waiter = new DataWaiter<LockMessage>();
			_waiter.Add(msg.RequestId, waiter);
			Send(id, msg);

			waiter.Waiter.WaitOne();

			_waiter.Remove(msg.RequestId);
		}

		public void Release(IService service, SpoonIdentifier id)
		{
			LockMessage msg = new LockMessage(service.Id, id);
			msg.Lock = LockMessage.LockType.Release;
			DataWaiter<LockMessage> waiter = new DataWaiter<LockMessage>();
			_waiter.Add(msg.RequestId, waiter);
			Send(id, msg);

			waiter.Waiter.WaitOne();

			_waiter.Remove(msg.RequestId);
		}

		private class LockItem
		{
			public ClientInfo Client;
			public DateTime Date = DateTime.Now;
		}

		public override void Start()
		{
			
		}

		public override void Stop()
		{
			
		}
	}
}
